defmodule PsqlRepo do
	@moduledoc """
	    ! 结尾的: 要抛出异常
	    非! 结尾的: 不抛出异常
	"""

	defmacro __using__(_env) do
		quote location: :keep do

			@doc """
			    opts: sql: "returning..."  | ON CONFLICT(*) DO ...
			"""
			@spec insert(charlist, [struct], keyword) :: list | charlist | nil
			def insert(project_id, list, opts \\ []) when is_list(list) do
				PsqlDb.insert(project_id, list, opts)
			end
			def insert(project_id, args, opts) do
				PsqlDb.insert(project_id, __MODULE__.new(args), opts)
			end

			# 不检查
			def update(project_id, update, where, opts \\ []) do
				PsqlDb.update(project_id, __MODULE__, update, where, opts)
			end
			# 要检查
			def update!(project_id, update, where, opts \\ []) do
				PsqlDb.update!(project_id, __MODULE__, update, where, opts)
			end

			def delete(project_id, where, opts \\ []) do
				PsqlDb.delete(project_id, __MODULE__, where, opts)
			end
			def delete!(project_id, where, opts \\ []) do
				PsqlDb.delete!(project_id, __MODULE__, where, opts)
			end


			def exists?(project_id, select, where) do
				PsqlDb.exists?(project_id, __MODULE__, select, where)
			end

			def read(project_id, select, where, opts \\ []) do
				PsqlDb.read(project_id, __MODULE__, select, where, opts)
			end
			def read!(project_id, select, where, opts \\ []) do
				PsqlDb.read!(project_id, __MODULE__, select, where, opts)
			end

			def count(project_id, where, opts \\ []) do
				PsqlDb.count(project_id, __MODULE__, where, opts)
			end

			def get_one(project_id, select, where, opts \\ []) do
				case PsqlDb.read(project_id, __MODULE__, select, where, opts) do
					[] ->
						opts[:default]
					[[row]] ->
						row
					[row | _] ->
						row
				end
			end

			defoverridable insert: 2,
										 update!: 3,
										 delete!: 2,
										 update: 3,
										 delete: 2

		end
	end

end
